//@author A0102103L
//
// **********
//
// modify class changes any parameter of a task, excluding status
// in the vector store
// in the txt store
// and in the currently displayed UI
//
// parameters include taskname,deadline,time,priority
//
// **********

#include "Modify.h"

Modify::Modify(void) {

}

Modify::~Modify(void) {

}

string Modify::execute(Task & task, vector<Task> & forUIDisplay, vector<Task> & store) {
	ofstream writeFile;
	writeFile.open(FILENAME_LOGGER.c_str(), ofstream::out | ofstream::app);
	writeFile << "Attempting to modify" << endl;
	writeFile.close();

	// if it is not empty, we are modifying via UNDO function
	if(task.getTaskName() == EMPTY) {
		if(task.getTaskLine() == NIL) {
			throw exception("Invalid modification");
		}

		if(task.getTaskLine() > forUIDisplay.size() || task.getTaskLine() < 0) {
			throw exception("Invalid modification");
		}
		
		int count = 0;
		if(task.getModifiedTaskName() != EMPTY) {
			int find = (task.getModifiedTaskName()).find_first_of("!@");
			if(find != string::npos) {
				throw exception ("you can only modify one thing at a time");
			}
			count++;
		}

		if(task.getModifiedDeadline() != EMPTY) {
			int find = (task.getModifiedDeadline()).find_first_of("!@");
			if(find != string::npos) {
				throw exception ("you can only modify one thing at a time");
			}
			count++;
		}
		if(task.getModifiedPriority() != EMPTY) {
			int find = (task.getModifiedDeadline()).find_first_of("@");
			if(find != string::npos) {
				throw exception ("you can only modify one thing at a time");
			}
			count++;
		}
		if(task.getModifiedTime() != EMPTY) {
			int find = (task.getModifiedDeadline()).find_first_of("!");
			if(find != string::npos) {
				throw exception ("you can only modify one thing at a time");
			}
			count++;
		}
		if(count != 1) {
			throw exception("Nothing to modify to");
		}
	
		//collection of data in case user wants to UNDO
		int userTaskLine = task.getTaskLine();
		task.changeTaskName(forUIDisplay[userTaskLine-1].getTaskName());
		task.changeDeadline(forUIDisplay[userTaskLine-1].getDeadline());
		task.changePriority(forUIDisplay[userTaskLine-1].getPriority());
		task.changeTime(forUIDisplay[userTaskLine-1].getTime());
		task.changeStatus(forUIDisplay[userTaskLine-1].getStatus());
		task.changeDateInSeconds(forUIDisplay[userTaskLine-1].getDateInSeconds());
	}



	//modifying in vector<Task> _store
	modifyFromStore(task,store);
			
	// modifying from txt file
	modifyFromStorage(task,store);

	// modifying from currently displayed list
	modifyFromUIDisplay(task,forUIDisplay);

	// settling printing
	string data = MODIFY_FEEDBACK;
	
	if(task.getModifiedTaskName() != task.getTaskName() && task.getModifiedTaskName() != EMPTY) {
		data += task.getTaskName();
		data += MODIFY_FEEDBACK1;
		data += task.getModifiedTaskName();
		data += MODIFY_FEEDBACK2;

	} else if (task.getModifiedDeadline() != task.getDeadline() && task.getModifiedDeadline() != EMPTY) {
		data += task.getDeadline();
		data += MODIFY_FEEDBACK1;
		data += task.getModifiedDeadline();
		data += MODIFY_FEEDBACK2;

	} else if (task.getModifiedPriority() != task.getPriority() && task.getModifiedPriority() != EMPTY) {
		data += task.getPriority();
		data += MODIFY_FEEDBACK1;
		data += task.getModifiedPriority();
		data += MODIFY_FEEDBACK2;
	
	} else if (task.getModifiedTime() != task.getTime() && task.getModifiedTime() != EMPTY) {
		data += task.getTime();
		data += MODIFY_FEEDBACK1;
		data += task.getModifiedTime();
		data += MODIFY_FEEDBACK2;
	
	} else if (task.getModifiedDateInSeconds() != task.getDateInSeconds() && task.getModifiedDateInSeconds() != NIL) {
		data = MODIFY_NIL_FEEDBACK;
	
	} else {
		data = MODIFY_SAME_STATUS_FEEDBACK;
	}
	

	if(task.getModifiedTaskName() == EMPTY) {
		task.changeModifiedTaskName(task.getTaskName());
	}
	if(task.getModifiedDeadline() == EMPTY) {
		task.changeModifiedDeadline(task.getDeadline());
		task.changeModifiedDateInSeconds(task.getDateInSeconds());
	}
	if(task.getModifiedPriority() == EMPTY) {
		task.changeModifiedPriority(task.getPriority());
	}
	if(task.getModifiedTime() == EMPTY) {
		task.changeModifiedTime(task.getTime());
	}
	
	return data;
}

void Modify::modifyFromStore(Task & task, vector<Task> & store) {
	ofstream writeFile;
	writeFile.open(FILENAME_LOGGER.c_str(), ofstream::out | ofstream::app);
	writeFile << "Attempting to modify from store" << endl;
	writeFile.close();
	
	for(vector<Task>::iterator iter = store.begin(); iter != store.end(); iter++) {
		Task currentTask = *iter;
	
		// all the conditions is to confirm in the case of similar tasknames
		if(currentTask.getTaskName() == task.getTaskName()) {
			if(currentTask.getDeadline() == task.getDeadline()) {
				if(currentTask.getPriority() == task.getPriority()) {
					if(currentTask.getTime() == task.getTime()) {
						if(currentTask.getDateInSeconds() == task.getDateInSeconds()) {
								
							if(task.getModifiedTaskName() != EMPTY) {
								(*iter).changeTaskName(task.getModifiedTaskName());
							}
							if(task.getModifiedDeadline() != EMPTY) {
								(*iter).changeDeadline(task.getModifiedDeadline());
							}
							if(task.getModifiedPriority() != EMPTY) {
								(*iter).changePriority(task.getModifiedPriority());
							}
							if(task.getModifiedTime() != EMPTY) {
								(*iter).changeTime(task.getModifiedTime());
							}
							if(task.getModifiedDeadline() != EMPTY) {
								(*iter).changeDateInSeconds(task.getModifiedDateInSeconds());
							}
							break;								
			
						}
					}
				}
			}
		}
	}


}

void Modify::modifyFromStorage(Task & task, vector<Task> & store) {
	ofstream writeFile;
	writeFile.open(FILENAME_LOGGER.c_str(), ofstream::out | ofstream::app);
	writeFile << "Attempting to modify from TXT storage" << endl;
	writeFile.close();

	vector<string> forTxtRewrite;
	Storage storage;
	Parser parse;
	string data;

	for(vector<Task>::iterator iter = store.begin(); iter != store.end(); iter++) {
		data = parse.convertToString(*iter);
		forTxtRewrite.push_back(data);
	}
	storage.rewrite(forTxtRewrite);
}

void Modify::modifyFromUIDisplay(Task & task, vector<Task> & forUIDisplay) {
	ofstream writeFile;
	writeFile.open(FILENAME_LOGGER.c_str(), ofstream::out | ofstream::app);
	writeFile << "Attempting to modify from UI Display" << endl;
	writeFile.close();

	
	for(vector<Task>::iterator iter = forUIDisplay.begin(); iter != forUIDisplay.end(); iter++) {
		Task currentTask = *iter;
		
		// all the conditions is to confirm in the case of similar tasknames
		if(currentTask.getTaskName() == task.getTaskName()) {
			if(currentTask.getDeadline() == task.getDeadline()) {
				if(currentTask.getPriority() == task.getPriority()) {
					if(currentTask.getTime() == task.getTime()) {
						if(currentTask.getDateInSeconds() == task.getDateInSeconds()) {
							
							if(task.getModifiedTaskName() != EMPTY) {
								(*iter).changeTaskName(task.getModifiedTaskName());
							}
							if(task.getModifiedDeadline() != EMPTY) {
								(*iter).changeDeadline(task.getModifiedDeadline());
							}
							if(task.getModifiedPriority() != EMPTY) {
								(*iter).changePriority(task.getModifiedPriority());
							}
							if(task.getModifiedTime() != EMPTY) {
								(*iter).changeTime(task.getModifiedTime());
							}
							if(task.getModifiedDeadline() != EMPTY) {
								(*iter).changeDateInSeconds(task.getModifiedDateInSeconds());
							}
							break;								
						}
					}
				}
			}
		}
	}


}